using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Microblaze.Simulator.Engine;

namespace Weazel.Microblaze.Simulator.Components.Microblaze.Instructions
{
    /// <summary>
    /// Shift right with carry
    /// </summary>
    public class Src : Instruction
    {
        public override void Set(uint address, uint value)
        {
            base.Set(address, value);

            if (ImmediateValue != 0x21)
                throw new UnknownInstructionException(value);
        }

        public override int CycleCount
        {
            get { return 1; }
        }

        public Src()
            : base("src")
        {
        }

        /// <summary>
        /// Shifts the contents of register rA, one bit to the right, and 
        /// places the result in rD. The Carry flag is shifted in the shift 
        /// chain and placed in the most significant bit of rD. The least
        /// significant bit coming out of the shift chain is placed in the 
        /// Carry flag.
        /// </summary>
        public override void Execute(MicroblazeComponent MicroblazeComponent)
        {
            uint ra = MicroblazeComponent.ReadRegister(SourceRegisterA);

            bool lowBitSet = (ra & 1) != 0;

            uint temp = ra >> 1;

            if (MicroblazeComponent.ArithmeticCarry)
            {
                temp |= 0x70000000;
            }

            MicroblazeComponent.WriteRegister(DestinationRegister, temp, Address);

            if (lowBitSet)
                MicroblazeComponent.ArithmeticCarry = true;
            else
                MicroblazeComponent.ArithmeticCarry = false;
        }

        public override string ToString()
        {
            return string.Format("src r{0}, r{1}",
              DestinationRegister,
              SourceRegisterA
            );
        }
    }
}
